;实验10（3）：数值显示(用10进制的方式显示内存中的二进制数据)
;子程序名称：dtoc
;功能：将word型数据转化为十进制数的以0结尾的字符串显示出来
;参数：(ax)= word型数据
;		ds:si 指向字符串首地址
;返回：无
;程序应用：把十进制数据12666以十进制形式打印在屏幕8行3列，绿色显示。（调用实验10中的第一个子程序show_str）
assume cs:code

data segment
	db 10 dup(0)
data ends


code segment
	start:
		mov ax,12666
		mov bx,data
		mov ds,bx
		mov si,0
		call dtoc 
		
		mov dh,8
		mov dl,3 
		mov cl,2
		call show_str
		
		mov ax,4c00h
		int 21h 
	dtoc:
		push bx
		push dx 
		push ds
		push si
		push cx
		push ax 
		
		mov bx,10
		ld:
			mov dx,0 
			div bx
			add dx,30h	; 十进制数码字符对应的ASCII码 = 十进制数码值 + 30H
			push dx						;把余数入栈，这里是利用堆栈后进先出的原理，下一步会进行输出，就形成逆序保存。
			inc si 
			mov cx,ax 
			jcxz okd
			jmp ld
		okd:
			mov cx,si
			sub si,si 					;从0开始
			ll:
				pop dx 					;从栈中弹出至dx寄存器，把余数+30H 以反序输出到ds:[0],[1].....
				mov byte ptr ds:[si],dl
				inc si 
			loop ll 
			mov byte ptr ds:[si],0 		;字符串最后补0，确保输入到show_str子程序的字符串是以0结尾的字符串
		pop ax
		pop cx
		pop si
		pop ds
		pop dx 
		pop bx 
		ret 
		
	show_str:	
		push ax
		push es
		push dx
		push bx
		push cx
		push si
		push di 
		mov ax,0b800h
		mov es,ax					;显存基地址
		mov ax,0
		mov di,0
		mov al,dh
		mov bl,0a0h
		mul bl 						;把0a0h和al相乘，存到ax中(所在行位置)
		mov bx,ax					;行存在bx里
		mov al,dl
		mov ah,0 
		mov ah,2
		mul ah
		add bx,ax 					;bx保存显存偏移地址~ax中存的是列号
		mov dh,cl					;颜色 存到dh中，8位正好，cl不方便（后面判断用到jcxz）
		l:	
			mov cl,[si]
			mov ch,0 
			mov ax,ds:[si]
			mov es:[di+bx],ax
			mov es:[di+1+bx],dh 
			jcxz ok
			inc si
			add di,2
			jmp l
		ok:	
			pop di
			pop si
			pop cx
			pop bx
			pop dx
			pop es
			pop ax 
		ret
code ends
end start
